package com.teng.dataStructure.arrayQueue;

import java.util.Scanner;

public class CircleArrayQueueDemo {
    public static void main(String[] args) throws Exception {
        //初始化
        CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4);
        //接收用户输入
        String key;
        Scanner scanner = new Scanner(System.in);
        //显示菜单
        boolean loop = true;
        while (loop) {
            System.out.println("s(show): 显示队列数据");
            System.out.println("h(head): 获取头数据");
            System.out.println("a(add): 添加一个数据至队列");
            System.out.println("g(get): 从队列中取出一个数据");
            System.out.println("e(exit): 退出程序");
            key = String.valueOf(scanner.next().charAt(0));
            switch (key) {
                case "s":
                    circleArrayQueue.showQueue();
                    break;
                case "h":
                    System.out.println("队列的头数据为：" + circleArrayQueue.getFront());
                    break;
                case "a":
                    System.out.println("请输入需要添加的数据");
                    circleArrayQueue.addQueue(scanner.nextInt());
                    break;
                case "g":
                    circleArrayQueue.getQueue();
                    break;
                case "e":
                    scanner.close();
                    loop = false;
                    break;
            }
        }
        System.out.println("程序退出");
    }
}

class CircleArrayQueue {
    private int front; //队列头,指向队列头的前一个位置
    private int rear; //队列尾
    private int maxSize; //队列最大容量
    private int[] arr; //模拟队列

    //创建队列的构造器
    public CircleArrayQueue(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[arrMaxSize];
    }

    //判断队列是否满
    public boolean isFull() {
        return (rear+1) % maxSize == front;
    }

    //判断队列是否空
    public boolean isEmpty() {
        return front == rear;
    }

    //往队列中添加数据
    public void addQueue(int x) {
        if (isFull()) {
            System.out.println("队列已满，无法添加数据");
            return;
        }
        arr[rear] = x;
        //不可以直接++，必须用取模的思想进行后移，否则会出现数组下标越界。front同理
        rear = (rear+1) % maxSize;
    }

    //从队列中提取数据
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，请先添加数据");
        }
        int value = arr[front];
        front = (front+1) % maxSize;
        return value;
    }

    //显示队列的所有数据
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空，无法读取数据！");
            return;
        }
        //1、将数组从front开始遍历
        //2、遍历元素个数：(rear+maxSize-front)%maxSize
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]: %d\n", i%maxSize, arr[i%maxSize]);
        }
    }

    //判断队列有效个数
    public int size(){
        return ((rear+maxSize-front)%maxSize);
    }

    //显示队列的头数据
    public int getFront() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，无头数据");
        }
        return arr[front];
    }
}
